package zmee.pmas.report;

import kd.bos.algo.DataSet;
import kd.bos.algo.DataType;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import zmee.common.allhelper.ReportTableHeadHelper;
import zmee.util.DateUtil;

import java.util.*;

/**
 * @author yss
 * @createTime 2022-12-26 10:14
 * @description 公司项目报表插件
 */
public class CompanyProQuery extends AbstractReportListDataPlugin {
    /**
     * 查询条件 - 项目
     */
    private final static String QUERY_ORG_QUERY = "zmee_org_query";
    /**
     * 查询条件 - 年度、月份
     */
    private final static String QUERY_YEARANDMONTH = "zmee_yearandmonth";
    /**
     * 查询条件 - 项目状态
     */
    private final static String QUERY_PROJECT_STATUS = "zmee_projectstatus";
    /**
     * 查询条件 - 项目分类
     */
    private final static String QUERY_PROJECT_GROUP = "zmee_progroupquery";

    @Override
    public DataSet query(ReportQueryParam queryParam, Object o) throws Throwable {

        //设置默认的查询条件
        //1、创建表单的时候字段带出当前登录人的组织
//        long userId = UserServiceHelper.getCurrentUserId();
////        2、获取当前登入人公司
//        UserServiceHelper.getUserMainOrgId(userId);
////        3、获取当前登入人部门
//        @SuppressWarnings("deprecation")
//        Map<String, Object> mapOrg = OrgServiceHelper.getCompanyfromOrg(Long.valueOf(UserServiceHelper.getUserMainOrgId(userId)));
        //1、获取所有的公司、项目组合
        DataSet compayProjectDataSet = getCompayProjectDataSet(queryParam);
        //获取年月
        Date qfilterValueDate = (Date) ReportTableHeadHelper.getQfilterValue(queryParam, QUERY_YEARANDMONTH);
        Integer yearInt = 0;
        Integer monthInt = 0;
        if(qfilterValueDate != null){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(qfilterValueDate);
            yearInt = calendar.get(Calendar.YEAR);
            monthInt = calendar.get(Calendar.MONTH);
            //2、获取预算类信息
            DataSet budgetDataSet = getBudgetDataSet(queryParam,yearInt);
            //合并信息
            compayProjectDataSet = ReportTableHeadHelper.leftJoinDataSet(compayProjectDataSet, budgetDataSet, new String[]{"zmee_yearbudget"}, getLeftJoinMap(), true);
            //3、获取支付类信息
            DataSet payDataSet = getPayDataSet(yearInt, monthInt);
            compayProjectDataSet = ReportTableHeadHelper.leftJoinDataSet(compayProjectDataSet, payDataSet, new String[]{"zmee_monthpay","zmee_totalpay","zmee_yearpay"}, getLeftJoinMap(), true);
            //4、获取到票类信息
            DataSet invoiceDataSet = getInvoiceDataSet(yearInt, monthInt);
            compayProjectDataSet = ReportTableHeadHelper.leftJoinDataSet(compayProjectDataSet, invoiceDataSet, new String[]{"zmee_totalbillamt","zmee_yearbillamt","zmee_monthbillamt"}, getLeftJoinMap(), true);
            //5、计算额外信息
        }
        return compayProjectDataSet;
    }

    /**
     * 获取所有的公司、项目组合
     * @param queryParam
     * @return
     */
    protected DataSet getCompayProjectDataSet(ReportQueryParam queryParam){
        //组织过滤
        QFilter proQFilter = ReportTableHeadHelper.getDyQfilter(queryParam, QUERY_ORG_QUERY, "org");
        //项目状态过滤
        QFilter proStatusQFilter = ReportTableHeadHelper.getDyCoQfilter(queryParam, QUERY_PROJECT_STATUS, "prostatus");
        //项目分类过滤
        QFilter proGroupQFilter = ReportTableHeadHelper.getDyCoQfilter(queryParam, QUERY_PROJECT_GROUP, "pro.group");
        //项目查询字段
        String[] selectors = new String[]{"pro zmee_project","prostatus","kind zmee_progroup","proleader zmee_proleader","org zmee_company"
                ,"prooutbudgetsumamt zmee_budgetamt"};
        //查询项目信息
        DataSet companyProDataSet = QueryServiceHelper.queryDataSet(getAlgo("getCompayProjectDataSet"), "pmas_pro_approval",
                String.join(",", selectors), new QFilter[]{proQFilter, proGroupQFilter, proStatusQFilter}, "org");
        if(companyProDataSet == null){
            companyProDataSet = ReportTableHeadHelper.createNullDataSet(getAlgo("getCompayProjectDataSet"),"null");
        }
        return companyProDataSet;
    }

    /**
     * 获取预算信息
     * @param queryParam
     * @return
     */
    protected DataSet getBudgetDataSet(ReportQueryParam queryParam,Integer year){
        //项目分类过滤
        QFilter proGroupQFilter = ReportTableHeadHelper.getDyCoQfilter(queryParam, QUERY_PROJECT_GROUP, "group");
        QFilter isValid = new QFilter("isvalid", QCP.equals, true);
        QFilter yearQFilter = getYearInfo(year,"year");
        //项目支出预算查询字段
        String[] selectors = new String[]{"project zmee_project","group zmee_progroup","totalamount zmee_yearbudget","year"};

        return QueryServiceHelper.queryDataSet(getAlgo("getBudgetDataSet"), "pmas_outbudget",
                String.join(",", selectors), new QFilter[]{proGroupQFilter, isValid,yearQFilter}, "year");
    }

    /**
     * 获取付款类信息
     * @param year
     * @param month
     * @return
     */
    protected DataSet getPayDataSet(Integer year,Integer month){
        //pmct_paymentregister
        //1、获取期间信息
        //累计：
        QFilter totalQFilter = new QFilter("period.periodyear",QCP.less_equals,year);
        //本年
        QFilter yearQFilter = new QFilter("period.periodyear",QCP.equals,year);
        //本月
        Date firstDayOfMonth = DateUtil.getFirstDayOfMonth(year,month);
        Date lastDayOfMonth = DateUtil.getLastDayOfMonth(year, month);
        QFilter periodQFilter = new QFilter("period.begindate",QCP.less_equals,firstDayOfMonth);
        periodQFilter.and(new QFilter("period.enddate",QCP.large_equals,lastDayOfMonth));
        //其他
        QFilter statusQFilter = new QFilter("billstatus",QCP.equals,"C");

        //项目查询字段
        String[] selectors = new String[]{"entryentity.contpro zmee_project","org zmee_company","entryentity.thispaymentoftaxamount payamonut"};
        String[] groupArr = new String[]{"zmee_project","zmee_company"};
        DataType[] typeArr = new DataType[]{DataType.LongType,DataType.LongType,DataType.BigDecimalType};
        //累计
//        String getPayDataSetTotal = getAlgo("getPayDataSetTotal");
//        DataSet getPayDataSetTotalDataSet = QueryServiceHelper.queryDataSet(getPayDataSetTotal,"pmct_paymentregister",
//                String.join(",",selectors),new QFilter[]{statusQFilter,totalQFilter},null);
//        DataSet getPayDataSetTotalTotalDataSet = getPayDataSetTotalDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getPayDataSetTotal,arrAddNewEle(groupArr,"zmee_totalpay"),typeArr) :
//                getPayDataSetTotalDataSet.copy().groupBy(groupArr).sum("payamonut","zmee_totalpay").finish();
        DataSet getPayDataSetTotalTotalDataSet = getTimeRangeAmtDataSet("getPayDataSetTotal","pmct_paymentregister",selectors,new QFilter[]{statusQFilter,totalQFilter},
                groupArr,typeArr,"payamonut","zmee_totalpay");
        //本年
//        String getPayDataSetYear = getAlgo("getPayDataSetYear");
//        DataSet getPayDataSetYearDataSet = QueryServiceHelper.queryDataSet(getPayDataSetYear,"pmct_paymentregister",
//                String.join(",",selectors),new QFilter[]{statusQFilter,yearQFilter},null);
//        DataSet getPayDataSetYearTotalDataSet = getPayDataSetYearDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getPayDataSetYear,arrAddNewEle(groupArr,"zmee_yearpay"),typeArr) :
//                getPayDataSetYearDataSet.copy().groupBy(groupArr).sum("payamonut","zmee_yearpay").finish();
        DataSet getPayDataSetYearTotalDataSet = getTimeRangeAmtDataSet("getPayDataSetYear","pmct_paymentregister",selectors,new QFilter[]{statusQFilter,yearQFilter},
                groupArr,typeArr,"payamonut","zmee_yearpay");
        //合并本年和累计
        getPayDataSetTotalTotalDataSet = ReportTableHeadHelper.leftJoinDataSet(getPayDataSetTotalTotalDataSet, getPayDataSetYearTotalDataSet, new String[]{"zmee_yearpay"}, getLeftJoinMap(), true);
        //本月
//        String getPayDataSetMonth = getAlgo("getPayDataSetMonth");
//        DataSet getPayDataSetMonthDataSet = QueryServiceHelper.queryDataSet(getPayDataSetMonth, "pmct_paymentregister",
//                String.join(",", selectors), new QFilter[]{statusQFilter, periodQFilter}, null);
//        //计算本月总和
//        DataSet getPayDataSetMonthTotalDataSet = getPayDataSetMonthDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getPayDataSetMonth,arrAddNewEle(groupArr,"zmee_monthpay"),typeArr) :
//                getPayDataSetMonthDataSet.copy().groupBy(groupArr).sum("payamonut","zmee_monthpay").finish();
        DataSet getPayDataSetMonthTotalDataSet = getTimeRangeAmtDataSet("getPayDataSetMonth","pmct_paymentregister",selectors,new QFilter[]{statusQFilter,periodQFilter},
                groupArr,typeArr,"payamonut","zmee_monthpay");
        //合并本月和累计
        getPayDataSetTotalTotalDataSet = ReportTableHeadHelper.leftJoinDataSet(getPayDataSetTotalTotalDataSet, getPayDataSetMonthTotalDataSet, new String[]{"zmee_monthpay"}, getLeftJoinMap(), true);

        return getPayDataSetTotalTotalDataSet;
    }

    /**
     * 获取发票类信息
     * @param year
     * @param month
     * @return
     */
    protected DataSet getInvoiceDataSet(Integer year,Integer month){
        //pmct_ininvoice
        //1、获取期间信息
        //累计：
        Date dateByYear = DateUtil.getDateByYear(year + 1);
        QFilter totalQFilter = new QFilter("invoicedate",QCP.less_equals,dateByYear);
        //本年
        QFilter yearQFilter = getYearInfo(year,"invoicedate");
        //本月
        Date firstDayOfMonth = DateUtil.getFirstDayOfMonth(year,month);
        Date lastDayOfMonth = DateUtil.getLastDayOfMonth(year, month);
        QFilter periodQFilter = new QFilter("invoicedate",QCP.less_equals,firstDayOfMonth);
        periodQFilter.and(new QFilter("invoicedate",QCP.large_equals,lastDayOfMonth));
        //其他
        QFilter statusQFilter = new QFilter("billstatus",QCP.equals,"C");

        //项目查询字段
        String[] selectors = new String[]{"project zmee_project","org zmee_company","totalamount"};
        String[] groupArr = new String[]{"zmee_project","zmee_company"};
        DataType[] typeArr = new DataType[]{DataType.LongType,DataType.LongType,DataType.BigDecimalType};
        //累计
//        String getInvoiceDataSetTotal = getAlgo("getInvoiceDataSetTotal");
//        DataSet getInvoiceDataSetTotalDataSet = QueryServiceHelper.queryDataSet(getInvoiceDataSetTotal,"pmct_ininvoice",
//                String.join(",",selectors),new QFilter[]{statusQFilter,totalQFilter},null);
//        DataSet getInvoiceDataSetTotalTotalDataSet = getInvoiceDataSetTotalDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getInvoiceDataSetTotal,arrAddNewEle(groupArr,"zmee_totalbillamt"),typeArr) :
//                getInvoiceDataSetTotalDataSet.copy().groupBy(groupArr).sum("totalamount","zmee_totalbillamt").finish();
        DataSet getInvoiceDataSetTotalTotalDataSet = getTimeRangeAmtDataSet("getInvoiceDataSetTotal","pmct_ininvoice",selectors,new QFilter[]{statusQFilter,totalQFilter},
                groupArr,typeArr,"totalamount","zmee_totalbillamt");
        //本年
//        String getInvoiceDataSetYear = getAlgo("getInvoiceDataSetYear");
//        DataSet getInvoiceDataSetYearDataSet = QueryServiceHelper.queryDataSet(getInvoiceDataSetYear,"pmct_ininvoice",
//                String.join(",",selectors),new QFilter[]{statusQFilter,yearQFilter},null);
//        DataSet getInvoiceDataSetYearTotalDataSet = getInvoiceDataSetYearDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getInvoiceDataSetYear,arrAddNewEle(groupArr,"zmee_yearbillamt"),typeArr) :
//                getInvoiceDataSetYearDataSet.copy().groupBy(groupArr).sum("totalamount","zmee_yearbillamt").finish();
        DataSet getInvoiceDataSetYearTotalDataSet = getTimeRangeAmtDataSet("getInvoiceDataSetYear","pmct_ininvoice",selectors,new QFilter[]{statusQFilter,yearQFilter},
                groupArr,typeArr,"totalamount","zmee_yearbillamt");
        //合并本年和累计
        getInvoiceDataSetTotalTotalDataSet = ReportTableHeadHelper.leftJoinDataSet(getInvoiceDataSetTotalTotalDataSet, getInvoiceDataSetYearTotalDataSet, new String[]{"zmee_yearbillamt"}, getLeftJoinMap(), true);
        //本月
//        String getInvoiceDataSetMonth = getAlgo("getInvoiceDataSetMonth");
//        DataSet getPayDataSetMonthDataSet = QueryServiceHelper.queryDataSet(getInvoiceDataSetMonth, "pmct_ininvoice",
//                String.join(",", selectors), new QFilter[]{statusQFilter, periodQFilter}, null);
//        //计算本月总和
//        DataSet getPayDataSetMonthTotalDataSet = getPayDataSetMonthDataSet == null ?
//                ReportTableHeadHelper.createNullDataSet(getInvoiceDataSetMonth,arrAddNewEle(groupArr,"zmee_monthbillamt"),typeArr) :
//                getPayDataSetMonthDataSet.copy().groupBy(groupArr).sum("totalamount","zmee_monthbillamt").finish();
        DataSet getPayDataSetMonthTotalDataSet = getTimeRangeAmtDataSet("getInvoiceDataSetMonth","pmct_ininvoice",selectors,new QFilter[]{statusQFilter,periodQFilter},
                groupArr,typeArr,"totalamount","zmee_monthbillamt");
        //合并本月和累计
        getInvoiceDataSetTotalTotalDataSet = ReportTableHeadHelper.leftJoinDataSet(getInvoiceDataSetTotalTotalDataSet, getPayDataSetMonthTotalDataSet, new String[]{"zmee_monthbillamt"}, getLeftJoinMap(), true);

        return getInvoiceDataSetTotalTotalDataSet;
    }

    private DataSet getTimeRangeAmtDataSet(String algo,String entityName,String[] selectors,QFilter[] qFilters,String[] groupArr,DataType[] dataTypes,String sumStr,String newStr){
        String getInvoiceDataSetMonth = getAlgo(algo);
        DataSet queryDataSet = QueryServiceHelper.queryDataSet(getInvoiceDataSetMonth, entityName,
                String.join(",", selectors), qFilters, null);
        //计算本月总和
        return queryDataSet == null ?
                ReportTableHeadHelper.createNullDataSet(getInvoiceDataSetMonth,arrAddNewEle(groupArr,newStr),dataTypes) :
                queryDataSet.copy().groupBy(groupArr).sum(sumStr,newStr).finish();
    }

    private String[] arrAddNewEle(String[] arr,String... newStr){
        List<String> allEle = new ArrayList<>(Arrays.asList(arr));
        allEle.addAll(Arrays.asList(newStr));
        return allEle.toArray(new String[0]);
    }

    private QFilter getYearInfo(Integer year,String dateStr){
        QFilter qFilter = QFilter.of("1=1");
        if(year == null){
            return qFilter;
        }
        //获取当年最开始时间和最后一天
        Date dateByYear = DateUtil.getDateByYear(year);
        //获取当年的开始时间
        Date firstTimeOfYear = DateUtil.getFirstTimeOfYear(dateByYear);
        //获取当年的结束时间
        Date endTimeOfYear = DateUtil.getEndTimeOfYear(dateByYear);
        qFilter.and(dateStr, QCP.large_equals,firstTimeOfYear);
        qFilter.and(dateStr, QCP.less_equals,endTimeOfYear);
        return qFilter;
    }

    private Map<String,String> getLeftJoinMap(){
        Map<String,String> leftJoinMap = new HashMap<>();
        leftJoinMap.put("zmee_project","zmee_project");
        return leftJoinMap;
    }

    private String getAlgo(String algoStr){
        return algoStr + ".aglo";
    }
}
